 #include <arrow_fill_cc.h>

// #include <arrow/result.h>
// #include <arrow/status.h>
// #include <arrow/array/data.h>
// #include <arrow/array/array_base.h>

#include <iostream>
// #include <vector>
#include <bitset>

std::shared_ptr<arrow::Array> holds_array;

/**
 *  withNulls 是否填充了空值
 * */
struct CxxArrowArray cxx_fill_ints(bool withNulls) {
    std::cout<<"CXX withNulls = " << withNulls << std::endl;
    // Make Arrays
    arrow::NumericBuilder<arrow::Int64Type> int64_builder;
    // Make place for 8 values in total
    int64_builder.Resize(8);

    std::vector<bool> validity = {true, true, true, true, true, true, true, true};
    // Bulk append the given values
    std::vector<int64_t> int64_values = {1, 2, 3, 4, 5, 6, 7, 8};

    if (withNulls) {  // 空值
      validity = {true, true, true, false, true, true, true, true};
      int64_values = {1, 2, 3, 0, 5, 6, 7, 8};
    }
    int64_builder.AppendValues(int64_values, validity);
    auto maybe_array =  int64_builder.Finish();
    if (!maybe_array.ok()) {
      //... do something on array building failure
    }
    std::shared_ptr<arrow::Array> int_array = *maybe_array;
    int64_builder.Reset();

    const uint8_t* null_bitmap = int_array->null_bitmap_data();
    std::vector<std::shared_ptr<arrow::Buffer>> buffers = int_array->data()->buffers;
    // if (buffers.size() == 2) {
      // const uint8_t* _null_bitmap = buffers[0]->data();
      const uint8_t* data = buffers[1]->data();
    // }
    int64_t len_null_bitmap = 0;
    
    if (buffers[0] != NULLPTR) {
      len_null_bitmap = buffers[0]->size();
    }
    int64_t len_data = buffers[1]->size();

    {
      std::cout<< "---------------------CXX cout---------------------"<<std::endl;
      if(buffers[0]!=NULLPTR) {
        std::cout<< "null_bitmap: length=" << len_null_bitmap << std::endl;
        std::cout<< "null_bitmap:  二进制 [";
        for(int i =0; i < len_null_bitmap; i++) {
          std::cout<<std::bitset<sizeof(uint8_t)*8>(null_bitmap[i])<<" ";
        }
        std::cout<<"]"<<std::endl;
        // std::cout<<"address: "<<null_bitmap<<std::endl;
        printf("address: %p\n", null_bitmap);
      }
      std::cout<< "data: length=" << len_data << std::endl;
      std::cout<< "data:  二进制 [";
        for(int i =0; i < len_data; i++) {
          std::cout<<std::bitset<sizeof(uint8_t)*8>(buffers[1]->data()[i])<<" ";
        }
        std::cout<<"]"<<std::endl;
        printf("address: %p\n", buffers[1]->data());
    }
    
    CxxArrowArray array = CxxArrowArray
    {
        len_null_bitmap,
        null_bitmap,
        len_data,
        data,
        int_array->length(),
        3,
        // arrow::int8() arrow::Type::INT8
        int_array
    };

  {
        printf("---------------Cxx printf-----------------");

        if(array.null_bitmap!=NULLPTR) {
        printf("null_bitmap: length=%ld\n", array.len_null_bitmap);
        printf("null_bitmap:  十进制 [");
        for(int i =0; i < array.len_null_bitmap; i++) {
            printf("%d ", array.null_bitmap[i]);
        }
        printf("]\n");
        printf("address: %p\n", array.null_bitmap);
        }
        printf("data: length=%ld\n", array.len_data);
        printf("data:  十进制 [");
        for(int i =0; i < array.len_data; i++) {
            printf("%d ", array.data[i]);
        }
        printf("]\n");
        printf("address: %p\n", array.data);
    }
    holds_array = int_array;
    return array;
  
}

void freeArrayPointer() {
  if (holds_array != NULLPTR) {
    holds_array = NULLPTR;
  }
}